/**
 * 
 */
package cc.dogtailflower.framework.util;

import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

import cc.dogtailflower.framework.exception.AppException;

/**
 * 类加载工具类
 * @author cc
 *
 */
public class ClassUtil {

	/*
	 * 获取类加载器
	 */
	public static ClassLoader getClassLoader(){
		return Thread.currentThread().getContextClassLoader();
	}
	
	/*
	 * 加载类
	 * className为全路径名，如cc.dogtailflower.util.ClassUtil
	 */
	public static Class<?> loadClass(String className){
		
		Class<?> cls;
		try{
			cls = Class.forName(className);
		}catch(ClassNotFoundException e){
			e.printStackTrace();
			throw new AppException(e.getMessage());
		}
		return cls;
	}
	
	/*
	 * 获取指定包名下的所有类信息，用递归(此处只考虑.class的自定义类，不考虑外部jar包中的类)
	 * packageName为全路径名如 cc.dogtailflower.util.ClassUtil
	 * 获取类的时候要加上前面完整路径，并且把.换成／
	 * 如/Users/cc/JavaProject/WebFramework/dogtailflower-web/framework/cc/dogtailflower/framework/util/ClassUtil.class
	 */
	public static Set<Class<?>> getClassSet(String packageName){  //cc.dogtailflower
		
		Set<Class<?>> classSet = new HashSet<Class<?>>();
		URL url = getClassLoader().getResource(packageName.replace(".", "/"));//file:/Users/cc/JavaProject/WebFramework/dogtailflower-web-framework/bin/cc/dogtailflower
		if(url != null){
			String protocol = url.getProtocol();
			if(protocol.equals("file")){
				String packagePath = url.getPath().replaceAll("%20", "");// %20表示空格 /Users/cc/JavaProject/WebFramework/dogtailflower-web-framework/bin/cc/dogtailflower
				findClass(classSet,packagePath,packageName);
			}
		}
		
		return classSet;
	}
	
	/*
	 * 递归查找类
	 * 加载并放入集合中
	 * classSet 类集合
	 * packagePath 文件路径名
	 * packageName 类路径名
	 */
	private static void findClass(Set<Class<?>> classSet,String packagePath,String packageName){
		
		
		File[] files = new File(packagePath).listFiles(new FileFilter(){//  /Users/cc/JavaProject/WebFramework/dogtailflower-web-framework/bin/cc/dogtailflower/framework
			//文件再做一次筛选，只需要.class文件或者 文件夹
			@Override
			public boolean accept(File file){
				return ((file.isFile() && file.getName().endsWith(".class")) || file.isDirectory());
			}
		}); 
		for(File file : files){
			String fileName = file.getName(); //framework   如果是文件的话例如:Configuration.class
			if(file.isFile()){
				String className = fileName.substring(0,fileName.lastIndexOf("."));  //Configuration
				if(StringUtil.isNotEmpty(packageName)){
					className = packageName + "." + className;  //cc.dogtailflower.framework.constant.Configuration
				}
				addLoadedClass(classSet,className);
			}else{
				String subPackagePath = fileName;
				if(StringUtil.isNotEmpty(packagePath)){
					subPackagePath = packagePath+"/"+subPackagePath; // /Users/cc/JavaProject/WebFramework/dogtailflower-web-framework/bin/cc/dogtailflower/framework
				}
				String subPackageName = fileName;
				if(StringUtil.isNotEmpty(packageName)){
					subPackageName = packageName + "." + subPackageName; //cc.dogtailflower.framework
				}
				findClass(classSet,subPackagePath,subPackageName);
			}
		}
	}
	
	/*
	 * 加载该类，并往集合中添加
	 * 往集合中类，
	 */
	private static void addLoadedClass(Set<Class<?>> classSet,String className){
		Class<?> cls = loadClass(className);
		classSet.add(cls);
	}
}
